﻿using FyAutoStartService.Models;
using FySystem.Logs;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace FyAutoStartService
{
    internal class AppManager
    {
        private static string _filePath = AppDomain.CurrentDomain.BaseDirectory + "apps.txt";

        /// <summary>
        /// 从配置文件中加载自启动程序列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal static List<AppInfo> LoadApps()
        {
            List<AppInfo> res = null;
            try
            {
                string json = string.Empty;

                using (FileStream fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read))
                {
                    using(StreamReader sr = new StreamReader(fs))
                    {
                        json = sr.ReadToEnd();
                    }
                }

                if(!string.IsNullOrWhiteSpace(json))
                {
                    res = JsonSerializer.Deserialize<List<AppInfo>>(json);
                }
                if (res == null)
                    res = new List<AppInfo>();
            }
            catch (Exception ex)
            {
                FyLogContextV2.WriteError(ex.Message);
            }
            return res;
        }

        /// <summary>
        /// 将自启程序保存到文件
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        internal static void SaveApps()
        {
            try
            {
                lock (Global.Apps)
                {
                    using (FileStream fs = new FileStream(_filePath, FileMode.Create, FileAccess.Write))
                    {
                        string jsn = JsonSerializer.Serialize(Global.Apps, Global.JsonOpt);
                        byte[] data = Encoding.UTF8.GetBytes(jsn);
                        fs.Write(data, 0, data.Length);
                        fs.Flush();
                    }
                }
            }
            catch (Exception ex)
            {
                FyLogContextV2.WriteError(ex.Message);
            }
        }

        /// <summary>
        /// 启动程序
        /// </summary>
        /// <param name="app"></param>
        /// <param name="isFore">是否无视IsAutoStart参数强制启动</param>
        /// <exception cref="NotImplementedException"></exception>
        internal static void StartUp(AppInfo app, bool isFore=false)
        {
            try
            {
                if (app == null)
                    throw new Exception("传入App信息为空~");

                if (app.IsAutoStart == false && isFore == false)
                    return;

                ProcessStartInfo pi = new ProcessStartInfo();
                pi.FileName = app.Path;
                if (!string.IsNullOrWhiteSpace(app.Args))
                    pi.Arguments = app.Args;

                if (app.Process != null)
                    app.Process.Dispose();

                app.Process = Process.Start(pi);
                app.CloseTime = null;
                FyLogContextV2.WriteLog($"程序启动:{app.Name}");
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 关闭程序
        /// </summary>
        /// <param name="app"></param>
        internal static void CloseApp(AppInfo app)
        {
            try
            {
                if (app == null) 
                    throw new Exception("传入App信息为空~");
                if (app.Process == null)
                    return;
                if (app.Process.HasExited == false)
                    app.Process.Kill();

                FyLogContextV2.WriteLog($"程序关闭:{app.Name}");
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 删除程序
        /// </summary>
        /// <param name="item"></param>
        /// <exception cref="NotImplementedException"></exception>
        internal static void DeleteApp(AppInfo item)
        {
            try
            {
                if (item == null)
                    throw new Exception("传入App信息为空~");
                
                //先关闭程序
                CloseApp(item);

                //再删除
                Global.Apps.Remove(item);

                FyLogContextV2.WriteLog($"删除程序:{item.Name}");
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
